home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 August / macformat-027.iso / mac / Shareware City / Developers / PlayerPRO 4.4.1 Dev.Kit / Import⁄Export / Okta2Mad.c < prev    next >
Encoding:
Text File  |  1995-04-04  |  11.4 KB  |  483 lines  |  [TEXT/MPCC]

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 4.4x -- OKTA to MADx
  4. //
  5. //    Version 1.0    - 12.3.95 ANR
  6. //
  7. //    To use with CodeWarrior 68K or PPC
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //    
  14. //    FAX:            (+41 22) 346 11 97
  15. //    Compuserve:    100277,164
  16. //    Internet:         rosset@dial.eunet.ch
  17. //
  18. /********************                        ***********************/
  19.  
  20. #include "Okta.h"
  21. #include "MAD.h"
  22. #include "RDriver.h"
  23. #include "PPInOut.h"
  24.  
  25. #if defined(powerc) || defined(__powerc)
  26. enum {
  27.         PlayerPROPlug = kCStackBased
  28.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  29.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  30.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr*)))
  31.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADPartition*)))
  32.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  33.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( short**)))
  34. };
  35.  
  36. ProcInfoType __procinfo = PlayerPROPlug;
  37. #else
  38. #include <A4Stuff.h>
  39. #endif
  40.  
  41. short decode16 (void *msg_buf)
  42. {
  43.   unsigned char *buf = msg_buf;
  44.   return ( (short) buf[0] << 8) | ( (short) buf[1]);
  45. }
  46.  
  47. unsigned long decode32 (void *msg_buf)
  48. {
  49.   unsigned char *buf = msg_buf;
  50.   
  51.   return( (unsigned long) buf[0] << 24) | ( (unsigned long) buf[1] << 16) | ( (unsigned long) buf[2] << 8) | ( (unsigned long) buf[3]);
  52. }
  53.  
  54. short FoundNote( short Period, short *MADpitchTable)
  55. {
  56. short    NCount = 1;
  57.     
  58.     while( NCount < NUMBER_NOTES+1)
  59.     {
  60.         if( Period >= MADpitchTable[ NCount]) return( NCount);
  61.         NCount++;
  62.     }
  63.     
  64.     return 0;
  65. }
  66.  
  67. struct Command* GetCommand( register short PosX, register short    TrackIdX, register    struct MusicPattern*    tempMusicPat)
  68. {
  69.     if( PosX < 0) PosX = 0;
  70.     else if( PosX >= tempMusicPat->header.PatternSize) PosX = tempMusicPat->header.PatternSize -1;
  71.         
  72.     return( & (tempMusicPat->Commands[ (tempMusicPat->header.PatternSize * TrackIdX) + PosX]));
  73. }
  74.  
  75. OSErr ConvertOKTA2Mad( Ptr    theOkta, long MODSize, MADPartition *theMAD, short *MADpitchTable)
  76. {
  77.     short                 i, PatMax, x, z, channel, TrueTracks;
  78.     long                     sndSize, OffSetToSample, OldTicks, temp, starting;
  79.     Ptr                    MaxPtr, theOktaPos;
  80.     OSErr                theErr;
  81.     Ptr                    theInstrument[ 120], destPtr;
  82.     unsigned    short        tempS;
  83.     char                    tempChar;
  84.     
  85.     
  86.     /**** Variables pour le MAD ****/
  87.     struct Command    *aCmd;
  88.  
  89.     /**** Variables pour le Okta ****/
  90.     
  91.     OktaHeader        *Okta;
  92.     OktaInstru            *samps, *s, instru[ 120];
  93.     OktaPattern         *OktaCmd;
  94.     sectheader        *aSect;
  95.     long                SectLength;
  96.     short            pbod_count, sbod_count;
  97.     /********************************/
  98.  
  99.     for( i = 0 ; i < 64; i ++) theInstrument[ i] = 0L;
  100.  
  101.     theMAD->header = (MADSpec*) NewPtrClear( sizeof( MADSpec));
  102.     Okta = ( struct OktaHeader*) NewPtr( sizeof( struct OktaHeader));
  103.  
  104.     sbod_count = 0;
  105.     pbod_count = 0;
  106.     
  107.     MaxPtr        = theOkta + MODSize;
  108.     theOktaPos    = theOkta;
  109.     
  110.     if( (*(long*)theOkta) != 'OKTA') DebugStr("\pError in OKTA");
  111.     
  112.     theOktaPos += 8L;
  113.     
  114.     while( theOktaPos < MaxPtr)
  115.     {
  116.         aSect = ( sectheader*) theOktaPos;
  117.         aSect->length = decode32 (&aSect->length);
  118.         
  119.         theOktaPos += 8L;
  120.  
  121.         switch( aSect->name)
  122.         {
  123.             case 'CMOD':
  124.                 Okta->splitted[0] = theOktaPos[1];
  125.                   Okta->splitted[1] = theOktaPos[3];
  126.                   Okta->splitted[2] = theOktaPos[5];
  127.                   Okta->splitted[3] = theOktaPos[7];
  128.                   Okta->linesize = ((4 +Okta->splitted[0] + Okta->splitted[1]
  129.                                + Okta->splitted[2] + Okta->splitted[3])
  130.                               * 4);
  131.             break;
  132.             
  133.             case 'SAMP':
  134.                 samps = (void*) theOktaPos;
  135.                   
  136.                 for( i = 0; i * sizeof( OktaInstru) < aSect->length; i++)
  137.                 {
  138.                     instru[i] = samps[i];
  139.                     
  140.                     instru[ i ].length = decode32 (&instru[ i ].length);
  141.                     instru[ i ].repeat = decode16 (&instru[ i ].repeat) * 2;
  142.                     instru[ i ].replen = decode16 (&instru[ i ].replen) * 2;
  143.                 }
  144.                 Okta->samp_count = i;
  145.             break;
  146.  
  147.             case 'SPEE':
  148.                 Okta->speed = decode16( theOktaPos);
  149.             break;
  150.  
  151.             case 'SLEN':
  152.                 Okta->slen = decode16( theOktaPos);
  153.             break;
  154.  
  155.             case 'PLEN':
  156.                 Okta->plen = decode16( theOktaPos);
  157.             break;
  158.  
  159.             case 'PATT':
  160.                 Okta->patt = (void*)theOktaPos;
  161.             break;
  162.  
  163.             case 'PBOD':
  164.                 Okta->pbodlen[ pbod_count] = decode16 (theOktaPos);
  165.                 
  166.                 if( pbod_count == 0) theMAD->header->Tracks = (aSect->length - 2L) / (Okta->pbodlen[ pbod_count] * 4L);
  167.                 else
  168.                 {
  169.                     if( theMAD->header->Tracks != (aSect->length - 2L) / (Okta->pbodlen[ pbod_count] * 4L))
  170.                     {
  171.                         DebugStr("\pNon-standard OKTA - Tracks");
  172.                     }
  173.                 }
  174.  
  175.                 Okta->pbod[ pbod_count++] = (theOktaPos + 2L);
  176.             break;
  177.  
  178.             case 'SBOD':
  179.                 s = &instru[ sbod_count];
  180.                 
  181.                 if (Okta->splitted[0] || Okta->splitted[1] || Okta->splitted[2] || Okta->splitted[3])
  182.                 {
  183.                 }
  184.                 
  185.                 if (s->length < aSect->length) s->length = aSect->length;
  186.                 
  187.                 theInstrument[ sbod_count] = theOktaPos;
  188.                 
  189.                 if (s->replen == 0)
  190.                 {
  191.                 }
  192.                 else if (s->repeat != 0)
  193.                 {
  194.                 }
  195.                 else
  196.                 {
  197.                 }
  198.                 
  199.                 sbod_count++;
  200.             break;
  201.  
  202.             default:
  203.                 DebugStr("\pUnknow section");
  204.             break;
  205.         }
  206.         theOktaPos += aSect->length;
  207.     }
  208.  
  209.     /******** Le Okta a été lu et analysé ***********/
  210.     /******** Copie des informations dans le MAD ***/
  211.  
  212.     theMAD->header->MADIdentification = 'MADF';
  213.     for(i=0; i<32; i++) theMAD->header->NameSignature[i] = 0;
  214.     for(i=0; i<20; i++) theMAD->header->NameSignature[i] = Okta->magic[i];
  215.     
  216.     theMAD->header->PatMax = pbod_count;
  217.     theMAD->header->numPointers = pbod_count;
  218.     for( i = 0;  i < 128; i++) theMAD->header->oPointers[ i] = 0;
  219.     for( i = 0;  i < pbod_count; i++) theMAD->header->oPointers[ i] = Okta->patt[ i];
  220.     
  221.     for(i=0; i< sbod_count; i++)
  222.     {
  223.         for( x = 0; x < 20; x++) theMAD->header->fid[i].Filename[x] = instru[i].name[ x];
  224.         theMAD->header->fid[i].insSize = instru[i].length;
  225.         theMAD->header->fid[i].fineTune = 0;
  226.         theMAD->header->fid[i].volume = instru[i].vol;
  227.         theMAD->header->fid[i].freq = 1;
  228.         theMAD->header->fid[i].amplitude = 8;
  229.         theMAD->header->fid[i].loopStart = instru[i].repeat;
  230.         theMAD->header->fid[i].loopLenght = instru[i].replen;
  231.         
  232.         if( theMAD->header->fid[i].insSize > 0)
  233.         {
  234.             theMAD->instrument[i] = NewPtr( theMAD->header->fid[i].insSize);
  235.             BlockMove( theInstrument[i], theMAD->instrument[i], theMAD->header->fid[i].insSize);
  236.         }
  237.         else theMAD->instrument[i] = 0L;
  238.     }
  239.     
  240.     for(i = sbod_count; i<64; i++)
  241.     {
  242.         theMAD->instrument[i] = 0L;
  243.         theMAD->header->fid[i].freq = 1;
  244.         theMAD->header->fid[i].amplitude = 8;
  245.         theMAD->header->fid[i].freq = 1;
  246.     }
  247.  
  248.     //*** TEMPORAIRE *****
  249.     
  250.     TrueTracks = theMAD->header->Tracks;
  251.     
  252.     theMAD->header->Tracks /= 2;
  253.     theMAD->header->Tracks *= 2;
  254.     if( theMAD->header->Tracks != TrueTracks) theMAD->header->Tracks += 2;
  255.     
  256.     for(i=0; i<theMAD->header->PatMax; i++)
  257.     {
  258.         theMAD->partition[ i] = (struct    MusicPattern*) NewPtrClear( sizeof( struct MusicPattern) + theMAD->header->Tracks * Okta->pbodlen[ i] * sizeof( struct Command));
  259.  
  260.         theMAD->partition[ i]->header.PatternSize = Okta->pbodlen[ i];
  261.         theMAD->partition[ i]->header.CompressionMode = 'NONE';
  262.         for( x = 0; x < 20; x++) theMAD->partition[ i]->header.PatternName[ x] = 0;
  263.         theMAD->partition[ i]->header.PatBytes = 0L;
  264.         theMAD->partition[ i]->header.unused2 = 0L;
  265.     
  266.         MaxPtr = (Ptr) theMAD->partition[ i];
  267.         MaxPtr += sizeof( struct MusicPattern) + theMAD->header->Tracks * Okta->pbodlen[ i] * sizeof( struct Command);
  268.  
  269.         for( x = 0; x < Okta->pbodlen[ i]; x++)
  270.         {
  271.             for(z=0; z<theMAD->header->Tracks; z++)
  272.             {
  273.                 aCmd = GetCommand( x, z, theMAD->partition[ i]);
  274.                 if( (Ptr) aCmd >= MaxPtr) Debugger();
  275.  
  276.                 if( z < TrueTracks)
  277.                 {
  278.                     OktaCmd = (OktaPattern*) (Okta->pbod[i] + x * TrueTracks * 4L + 4L*z);
  279.  
  280.                     if( OktaCmd->b1 > 0)
  281.                     {
  282.                         aCmd->AmigaPeriod = FoundNote( FreqOktaTable[ OktaCmd->b1 - 1], MADpitchTable);
  283.                         aCmd->InstrumentNo = OktaCmd->b2 + 1;
  284.                         if( theInstrument[ aCmd->InstrumentNo] == 0L)
  285.                         {
  286.                             aCmd->InstrumentNo = 0;
  287.                             aCmd->AmigaPeriod = 0;
  288.                         }
  289.                     }
  290.  
  291.                     switch( OktaCmd->b3)
  292.                     {
  293.                         case 31:
  294.                             if (OktaCmd->b4 <= 0x40)
  295.                             {
  296.                                 aCmd->EffectCmd = volumeE;
  297.                                 aCmd->EffectArg = OktaCmd->b4;
  298.                             }
  299.                         break;
  300.                     
  301.                         case 25:
  302.                             OktaCmd->b4 &= 0xf;
  303.                               if(    OktaCmd->b4 != 0)
  304.                               {
  305.                                   aCmd->EffectCmd = speedE;
  306.                                   aCmd->EffectArg = OktaCmd->b4;
  307.                               }
  308.                         break;
  309.                     }
  310.                     
  311.                     if( i == 0 && x == 0 && z == 0)
  312.                     {
  313.                         aCmd->EffectCmd        = speedE;
  314.                         aCmd->EffectArg        = Okta->speed;
  315.                     }
  316.                 }
  317.                 else
  318.                 {
  319.                     aCmd->AmigaPeriod    = 0;
  320.                     aCmd->InstrumentNo    = 0;
  321.                     aCmd->EffectCmd     = 0;
  322.                     aCmd->EffectArg     = 0;
  323.                 }
  324.             }
  325.         }
  326.     }
  327.  
  328.     DisposPtr( (Ptr) Okta);
  329.  
  330.     return noErr;
  331. }
  332.  
  333. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  334. {
  335.     register short len, i;
  336.     
  337.     len = *s2;
  338.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  339. }
  340.  
  341. OSErr ExtractOKTAInfo( PPInfoRec *info, Ptr AlienFile)
  342. {
  343.     long        PatternSize;
  344.     short    i;
  345.     short    maxInstru;
  346.     short    tracksNo;
  347.     
  348.     /*** Signature ***/
  349.     
  350.     info->signature = 'OKTA';
  351.     
  352.     /*** Internal name ***/
  353.     
  354.     pStrcpy( info->internalFileName, "\p");
  355.  
  356.     /*** Total Patterns ***/
  357.     
  358.     info->totalPatterns = 0;
  359.     
  360.     /*** Partition Length ***/
  361.     
  362.     info->partitionLength = 0;
  363.     
  364.     /*** Total Instruments ***/
  365.     
  366.     info->totalInstruments = 0;
  367.     
  368.     pStrcpy( info->formatDescription, "\pOKTA Plug");
  369.  
  370.     return noErr;
  371. }
  372.  
  373. OSErr TestOKTAFile( Ptr AlienFile)
  374. {
  375. long    *myOKTA = ( long*) AlienFile;
  376.  
  377. if( *myOKTA == 'OKTA') return   noErr;
  378. else return  fileNotSupportedByThisPlug;
  379. }
  380.  
  381. OSErr main( OSType order, FSSpec *AlienFileFSSpec, MADPartition *MadFile, PPInfoRec *info, short *MADpitchTable)
  382. {
  383.     OSErr    myErr;
  384.     Ptr        AlienFile;
  385.     short    vRefNum, iFileRefI;
  386.     long    dirID, sndSize;
  387.     
  388. #ifndef powerc
  389.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  390. #endif
  391.  
  392.     HGetVol( 0L, &vRefNum, &dirID);
  393.     HSetVol( 0L, AlienFileFSSpec->vRefNum, AlienFileFSSpec->parID);
  394.  
  395.     myErr = noErr;
  396.  
  397.     switch( order)
  398.     {
  399.         case 'IMPL':
  400.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  401.             if( myErr == noErr)
  402.             {
  403.                 GetEOF( iFileRefI, &sndSize);
  404.             
  405.                 // ** MEMORY Test Start
  406.                 AlienFile = NewPtr( sndSize * 2L);
  407.                 if( AlienFile == 0L) myErr = needMoreMemory;
  408.                 // ** MEMORY Test End
  409.                 
  410.                 else
  411.                 {
  412.                     DisposPtr( AlienFile);
  413.                     
  414.                     AlienFile = NewPtr( sndSize);
  415.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  416.                     if( myErr == noErr)
  417.                     {
  418.                         myErr = TestOKTAFile( AlienFile);
  419.                         if( myErr == noErr)
  420.                         {
  421.                             myErr = ConvertOKTA2Mad( AlienFile,  GetPtrSize( AlienFile), MadFile, MADpitchTable);
  422.                         }
  423.                     }
  424.                     DisposPtr( AlienFile);    AlienFile = 0L;
  425.                 }
  426.                 FSClose( iFileRefI);
  427.             }
  428.         break;
  429.         
  430.         case 'TEST':
  431.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  432.             if( myErr == noErr)
  433.             {
  434.                 sndSize = 1024L;
  435.                 
  436.                 AlienFile = NewPtr( sndSize);
  437.                 if( AlienFile == 0L) myErr = needMoreMemory;
  438.                 else
  439.                 {
  440.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  441.                     myErr = TestOKTAFile( AlienFile);
  442.                     
  443.                     DisposPtr( AlienFile);    AlienFile = 0L;
  444.                 }
  445.                 FSClose( iFileRefI);
  446.             }
  447.         break;
  448.  
  449.         case 'INFO':
  450.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  451.             if( myErr == noErr)
  452.             {
  453.                 GetEOF( iFileRefI, &info->fileSize);
  454.             
  455.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  456.                 
  457.                 AlienFile = NewPtr( sndSize);
  458.                 if( AlienFile == 0L) myErr = needMoreMemory;
  459.                 else
  460.                 {
  461.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  462.                     if( myErr == noErr)
  463.                     {
  464.                         myErr = ExtractOKTAInfo( info, AlienFile);
  465.                     }
  466.                     DisposPtr( AlienFile);    AlienFile = 0L;
  467.                 }
  468.                 FSClose( iFileRefI);
  469.             }
  470.         break;
  471.         
  472.         default:
  473.             myErr = orderNotImplemented;
  474.         break;
  475.     }
  476.  
  477.     HSetVol( 0L, vRefNum, dirID);
  478.  
  479.     #ifndef powerc
  480.         SetA4( oldA4);
  481.     #endif
  482.     return myErr;
  483. }